﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpDwgDxfInterface.h"
#include "AcadVersion.h"
#include "Vector3d.h"
#include "GcmpApiDeclaration.h"
#include "ElementId.h"

namespace gcmp
{
    class IDocument;
    class IModelView;
    class IElement;
    class IGraphicsNodePath;
    class ICADDimension;

    class ICADTextStyle;
    class ICADDimensionStyle;
    class ILayerSettings;
    class IExportCustomizer;
    class IPDFExportParams;

    //视图导出设置
    struct ExportViewSetting
    {
        ElementId modelViewId = ElementId::InvalidID;         ///<  视口对应的ModelView。缺省为空。
        IDocument* pDocument = nullptr;          ///<  文档指针
        std::wstring sBlockName;       ///<  视图块名称
        double dScale = 1.0;                 ///<  缩放比例,默认1.0
        bool ShouldExportTitle = true;        ///<  是否需要导出视口的标题。true表示需要导出视口的标题；false表示不需要导出视口的标题。缺省为true。
        bool ShouldExportHideEdges = false;    ///<  是否导出隐藏线。true表示该视口整体上需要导出隐藏线；false表示该视口整体不需要导出隐藏线。缺省为false。
        bool KeepHighHiddenEdges = true;      ///<  导出隐藏线过程，如果隐藏线在视线方向存在遮挡，true表示保留高程较高的隐藏线，false表示保留高程较低的隐藏线
        bool bUseHLRAcc = true;               ///<  导出过程是否使用消隐（HLRAcc）加速，默认使用加速。由于加速算法与分辨率相关，当图幅范围非常大，且要求精细显示时，
                                       ///<  可能因分辨率不足导致消隐结果出错。此时建议bUseHLRAcc传false，这样可以保障结果正确，不过导出效率会有所下降。
        double dHLRRegionSearchTolerance = 0.01;///<消隐后区域的搜环精度。默认为0.01，对于模型存在瑕疵/裂缝时可设置为0.1；设置为0.001将更加严格和精确
        double dHLRRegionRepairTolerance = 10.0;///<搜索消隐后区域时，当区域不封闭时修复精度。GGP默认为10，设置越小越精确
        bool IsBigNurbsIntersect = true;///<设置超大nurbs曲面是否参与计算交线。GGP默认为true，当因超大Nurbs曲面求交产生效率问题时(BIMMAKE场布场景中使用)，建议设置为false。
        int nMaxTriangleCountOfBody = -1;///<单个body的最大离散三角面个数，超过这个值消隐计算不执行，-1不做检查
        ExportViewSetting(){}
    };

    // 收集文字样式回调函数。
    // 如果需要通过收集所有出图文本节点，来设置对应的文字样式，则需要实现此回调函数，并在调用导出dwg/dxf/pdf前指定给出图接口实例。
    // 外部调用者可以通过实现此回调函数用下面两种方式实现添加文字样式的目的：
    //      1、根据回调参数生成一个OwnerPtr<ICADTextStyle>对象，并在回调函数内调用出图接口实例的
    //         void IDrawingExporter::AddCustomTextStyle(OwnerPtr<ICADTextStyle>& cadTextStyle)方法
    //      2、根据回调参数生成一个OwnerPtr<ICADTextStyle>对象，并将此对象放到调用者的数据集合中，
    //         然后在回调函数外部，调用出图接口示例的void IDrawingExporter::AddCustomTextStyle(OwnerPtr<ICADTextStyle>& cadTextStyle)方法
    typedef void(*CollectTextStyleCallback)(const gcmp::IElement* pElement, const gcmp::IModelView* pModelView, const gcmp::IGraphicsNodePath* pPath);

    /// \brief 图纸导出接口
    class GCMP_DWG_DXF_INTERFACE_EXPORT IDrawingExporter
    {
    public:
        /*!
        *@brief      创建图纸导出器
        *@param[in]  pDocument 模型文档
        *@param[in]  settings  导出视图设置
        *@return OwnerPtr<IDrawingExporter> 图纸导出器对象
        */
        static OwnerPtr<IDrawingExporter> Create(IDocument* pDocument, const std::vector<ExportViewSetting>& settings);

        virtual ~IDrawingExporter() {};

        /*!
        *@brief      设置导出精度
        *@param[in]  dEpsilon 导出精度
        */
        virtual void SetExportEpsilon(double dEpsilon) = 0;
        /*!
        *@brief      设置是否导出xdata数据，默认导出
        *@param[in]  isExport
        */
        virtual void SetIsExportXData(bool isExport) = 0;
        virtual bool GetIsExportXData() const = 0;
        /*!
        *@brief      设置RegApp的名称，默认为"GBMP"
        *@param[in]  const std::wstring& strRegAppName 名称
        */
        virtual void SetXDataRegAppName(const std::wstring& strRegAppName) = 0;
        virtual std::wstring GetXDataRegAppName() const = 0;
        /*!
        *@brief      添加自定义填充文件
        *@param[in]  strHatchFile 填充文件路径
        */
        virtual void AddCustomHatchFile(const std::wstring& strHatchFile) = 0;
        
        /*!
        *@brief      设置“收集自定义文字样式”的回调函数
        *@param[in]  fp “收集自定义文字样式”的回调函数指针
        */
        virtual void IDrawingExporter::SetCollectTextStyleCallback(CollectTextStyleCallback fp) = 0;
        
        /*!
        *@brief      添加自定义文字样式
        *@param[in]  cadTextStyle 文字样式
        */
        virtual void AddCustomTextStyle(OwnerPtr<ICADTextStyle>& cadTextStyle) = 0;

        /*!
        *@brief      添加自定义标注样式
        *@param[in]  dimensionStyle 标注样式
        */
        virtual void AddCustomDimensionStyle(OwnerPtr<ICADDimensionStyle>& dimensionStyle) = 0;
        /*!
        *@brief      添加图层设置
        *@param[in]  layerSetting 图层设置
        */
        virtual void AddLayerSetting(OwnerPtr<ILayerSettings>& layerSetting) = 0;

        /*!
        *@brief      设置导出自定义回调
        *@param[in]  exportCustomizer 导出自定义回调
        */
        virtual void SetExportCustomizer(OwnerPtr<IExportCustomizer>& exportCustomizer) = 0;

        /*!
        *@brief      设置颜色随视图
        *@param[in]  bByView 颜色随视图
        */
        virtual void SetColorByView(bool bByView) = 0;

        /*!
        *@brief      设置线样式随视图
        *@param[in]  bByView 线样式随视图
        */
        virtual void SetLineStyleByView(bool bByView) = 0;

        /*!
        *@brief      设置是否删除无用的图层和文字样式
        *@param[in]  bDeleteUselessLayerAndTextStyle为true 删除无用的图层和文字样式
        */
        virtual void SetIsDeleteUselessLayerAndTextStyle(bool bDeleteUselessLayerAndTextStyle) = 0;

        /*!
        *@brief      设置是否允许Line2d类型的线导出为Polyline线
        *@param[in]  bEnable为true Line2d类型的线导出为Polyline线，false将导出为Line。导出后的Polyline支持全局线宽，Line则不支持
        */
        virtual void SetEnableExportLine2dToPolyline(bool bEnable) = 0;
        virtual bool IsEnableExportLine2dToPolyline(void) const = 0;

        /*!
        *@brief      设置导出DWG模板文件的全路径文件名
        *@param[in]  strDwtFileName 导出DWG模板文件的全路径文件名，如"D:\\GCMP_CONIFG\\export.dwt"
        */
        virtual void SetDwtFileName(const std::wstring& strFileName) = 0;

        /*!
        *@brief      设置导出dwg图纸的全局线型比例因子。模板文件的优先级高，即如果调用了SetDwtFileName(const std::wstring& strFileName)，且文件有效，则此方法不生效
        *@param[in]  dScale dwg图纸的全局线型比例因子，应大于0
        *@return     bool 如果dScale不合法返回false，否则返回true
        */
        virtual bool SetDrawingLineTypeScale(double dScale) = 0;

        /*!
        *@brief      设置多段线是否允许线型生成开启，对应CAD中的多段线的Plinegen属性
        *@param[in]  bEnable为true 导出的Polyline线开启线型生成，false禁用线型生成
        */
        virtual void SetEnablePolylinegen(bool bEnable) = 0;

        /*!
        *@brief      设置是否导出与填充遮罩边界重合的线或边
        *@param[in]  bEnable为true 导出，false 不导出
        */
        virtual void SetEnableExportOverlappingCurve2dWithMaskRegionBorderline(bool bEnable) = 0;

        /*!
        *@brief      设置是否导出多段线高程信息,要求多段线的平面和视图平面平行;高程是多段线的Z值;
        *@param[in]  bEnable为true 导出，false 不导出
        */
        virtual void SetExportPolylineElevation(bool bExport) = 0;

        /*!
        *@brief      设置是否允许导出dwg内容遵循渲染层级优先级偏移
        *@param[in]  bEnable为true 支持，false 不支持
        */
        virtual void SetEnableSupportRenderPriorityOffset(bool bEnable) = 0;

        /*!
        *@brief      设置链接模型是否导出为图块
        *@param[in]  bEnable为true 链接模型按图块导出，false 不按图块
        */
        virtual void SetEnableLinkModelToBlock(bool bEnable) = 0;

        /*!
        *@brief      设置是否使用CDT离散区域搜索算法
        *@param[in]  bEnable true使用CDT，false使用搜环算法
        */
        virtual void SetEnableCDTHLRRegionSearcher(bool bEnable) = 0;

        /*!
        *@brief      当导出模式为 HLR_BODY_CURVE_TEXT 时，文字的导出条件
        *@param[in]  bEnable为true文字全部可见才导出, false文字全部不可见才不导出
        */
        virtual void SetTextExportedByWholeVisibility(bool bEnable) = 0;

        /*!
        *@brief      导出DWG
        *@param[in]  strFilePath 文件路径
        *@param[in]  version CAD版本
        *@return     bool 如果成功导出文件返回true，否则返回false
        */
        virtual bool ExportToDwg(const std::wstring& strFilePath, AcadVersion version) = 0;

        /*!
        *@brief      导出PDF
        *@param[in]  strFilePath 文件路径
        *@param[in]  pdfExportParam pdf导出参数
        *@return     bool 如果成功导出文件返回true，否则返回false
        */
        virtual bool ExportToPdf(const std::wstring& strFilePath, const gcmp::IPDFExportParams& pdfExportParam) = 0;

        /*!
        *@brief      导出DXF
        *@param[in]  strFilePath 文件路径
        *@param[in]  version CAD版本
        */
        virtual void ExportToDxf(const std::wstring& strFilePath, AcadVersion version) = 0;

        GCMP_OBSOLETE_API(2022/01/01, IDrawingExporter::ExportToPdf(const std::wstring&, AcadVersion)) virtual void IDrawingExporter::ExportToDxf(const std::wstring& strFilePath) = 0;      
    };
}
